home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Tool Chest / Text / WASTE / WASTE 1.1.2 Distribution / Demo Source / WEDemoEvents.p < prev    next >
Encoding:
Text File  |  1995-10-12  |  10.6 KB  |  449 lines  |  [TEXT/CWIE]

  1. unit WEDemoEvents;
  2.  
  3. { WASTE DEMO PROJECT: }
  4. { Events Handling }
  5.  
  6. { Copyright © 1993-1995 Marco Piovanelli }
  7. { All Rights Reserved }
  8.  
  9. interface
  10.     uses
  11.         WEDemoIntf;
  12.  
  13.     function InitializeEvents: OSErr;
  14.     procedure DoWindowEvent ({const} var event: EventRecord);
  15.     procedure ProcessEvent;
  16.  
  17. implementation
  18.     uses
  19.         AppleEvents, AERegistry, DiskInit, TextServices, WEDemoMenus, WEDemoScripting, WEDemoWindows;
  20.  
  21.     const
  22.  
  23. { possible values for HandleOpenDocument refCon parameter }
  24.  
  25.         kDoOpen = 0;
  26.         kDoPrint = 1;
  27.  
  28.     var
  29.  
  30.         gSleepTime: LongInt;                    { sleep time for WaitNextEvent }
  31.         gMouseRgn: RgnHandle;                { mouse region for WaitNextEvent }
  32.  
  33.     procedure AdjustCursor (mouseLoc: Point;
  34.                                     mouseRgn: RgnHandle);
  35.         var
  36.             window: WindowRef;
  37.     begin
  38.  
  39. { by default, set mouseRgn to the whole QuickDraw coordinate plane, }
  40. { so that we never get mouse moved events }
  41.         SetRectRgn(mouseRgn, -maxint, -maxint, maxint, maxint);
  42.  
  43. { give text services a chance to set the cursor shape }
  44.         if (gHasTextServices) then
  45.             if (SetTSMCursor(mouseLoc)) then
  46.                 Exit(AdjustCursor);
  47.  
  48. { if there is a window open, give WEAdjustCursor an opportunity to set the cursor }
  49. { WEAdjustCursor intersects mouseRgn (if supplied) with a region within which }
  50. { the cursor is to retain its shape. }
  51. { (if the cursor is outside the view region, this is subtracted from mouseRgn) }
  52.  
  53.         window := FrontWindow;
  54.         if (window <> nil) then
  55.             if (WEAdjustCursor(mouseLoc, mouseRgn, DocumentPeek(window)^.we)) then
  56.                 Exit(AdjustCursor);
  57.  
  58. { set the cursor to the arrow cursor }
  59. {$IFC NOT UNDEFINED THINK_PASCAL}
  60.         SetCursor(arrow);
  61. {$ELSEC}
  62.         SetCursor(qd.arrow);
  63. {$ENDC}
  64.  
  65.     end;  { AdjustCursor }
  66.  
  67.     procedure DoMouseDown ({const} var event: EventRecord);
  68.         var
  69.             window: WindowRef;
  70.             partCode: Integer;
  71.     begin
  72.  
  73. { find out where this click went down in }
  74.         partCode := FindWindow(event.where, window);
  75.  
  76. { dispatch on partCode }
  77.         case partCode of
  78.  
  79.             inMenuBar: 
  80.                 begin
  81.                     PrepareMenus;
  82.                     DoMenuChoice(MenuSelect(event.where));
  83.                 end;
  84.  
  85.             inSysWindow: 
  86.                 SystemClick(event, window);
  87.  
  88.             inContent: 
  89.                 if (DoContent(event.where, event, window)) then
  90.                     SelectWindow(window);
  91.  
  92.             inDrag: 
  93.                 DoDrag(event.where, window);
  94.  
  95.             inGrow: 
  96.                 DoGrow(event.where, window);
  97.  
  98.             inGoAway: 
  99.                 if (TrackGoAway(window, event.where)) then
  100.                     if (DoClose(closingWindow, savingAsk, window) <> noErr) then
  101.                         ;
  102.  
  103.             inZoomIn, inZoomOut: 
  104.                 if (TrackBox(window, event.where, partCode)) then
  105.                     DoZoom(partCode, window);
  106.  
  107.             otherwise
  108.                 ;
  109.         end;  { case partCode }
  110.     end;  { DoMouseDown }
  111.  
  112.     procedure DoKeyDown ({const} var event: EventRecord);
  113.         const
  114.  
  115. { virtual key codes generated by some function keys }
  116.             keyF1 = $7A;
  117.             keyF2 = $78;
  118.             keyF3 = $63;
  119.             keyF4 = $76;
  120.         var
  121.             key: Char;
  122.     begin
  123.  
  124. { extract character code from event message }
  125.         key := Char(BAND(event.message, charCodeMask));
  126.  
  127. { map function keys to the equivalent command+key combos }
  128. { note that all function keys generate the same character code, i.e. $10 }
  129.         if (key = CHR($10)) then
  130.             begin
  131.                 event.modifiers := BOR(event.modifiers, cmdKey);
  132.                 case BSR(BAND(event.message, keyCodeMask), 8) of
  133.  
  134.                     keyF1: 
  135.                         key := 'z';
  136.  
  137.                     keyF2: 
  138.                         key := 'x';
  139.  
  140.                     keyF3: 
  141.                         key := 'c';
  142.  
  143.                     keyF4: 
  144.                         key := 'v';
  145.  
  146.                     otherwise
  147.                         key := CHR(0);
  148.                 end;  { case }
  149.             end;
  150.  
  151. { command + printable character combos are routed to MenuKey }
  152.         if (BAND(event.modifiers, cmdKey) <> 0) and (key >= CHR(32)) then
  153.             begin
  154.                 PrepareMenus;
  155.                 DoMenuChoice(MenuKey(key));
  156.             end
  157.         else
  158.             DoKey(key, event);
  159.     end;  { DoKeyDown }
  160.  
  161.     procedure DoDiskEvent ({const} var event: EventRecord);
  162.         var
  163.             dialogCorner: Point;
  164.             err: OSErr;
  165.     begin
  166.         if (BSR(event.message, 16) <> noErr) then
  167.             begin
  168.                 SetPt(dialogCorner, 112, 80);
  169.                 err := DIBadMount(dialogCorner, event.message);
  170.             end;
  171.     end;  { DoDiskEvent }
  172.  
  173.     procedure DoOSEvent ({const} var event: EventRecord);
  174.         var
  175.             osMessage: Integer;
  176.             window: WindowRef;
  177.     begin
  178.  
  179. { extract the OS message field from the event record }
  180.         osMessage := BSR(BAND(event.message, osEvtMessageMask), 24);
  181.  
  182. { dispatch on osMessage }
  183.         case osMessage of
  184.  
  185.             suspendResumeMessage: 
  186.                 begin
  187.                     window := FrontWindow;
  188.                     if (window <> nil) then
  189.                         DoActivate(BAND(event.message, resumeFlag) <> 0, window);
  190.                 end;
  191.  
  192.             mouseMovedMessage: 
  193.                 ;
  194.  
  195.             otherwise
  196.                 ;
  197.         end;  { case }
  198.     end;  { DoOSEvent }
  199.  
  200.     procedure DoHighLevelEvent ({const} var event: EventRecord);
  201.     begin
  202.         if (AEProcessAppleEvent(event) <> noErr) then
  203.             ;
  204.     end;  { DoHighLevelEvent }
  205.  
  206.     procedure DoNullEvent ({const} var event: EventRecord);
  207.         var
  208.             window: WindowRef;
  209.     begin
  210.         window := FrontWindow;
  211.         if (window <> nil) then
  212.             WEIdle(gSleepTime, DocumentPeek(window)^.we)
  213.         else
  214.             gSleepTime := maxLongInt;
  215.     end;  { DoNullEvent }
  216.  
  217.     procedure DoWindowEvent ({const} var event: EventRecord);
  218.         var
  219.             window: WindowRef;
  220.     begin
  221.  
  222. { the message field of the event record contains the window pointer }
  223.         window := WindowRef(event.message);
  224.  
  225. { make sure this window is an application window; check the windowKind field }
  226.         if (WindowPeek(window)^.windowKind <> userKind) then
  227.             Exit(DoWindowEvent);
  228.  
  229.         case event.what of
  230.  
  231.             updateEvt: 
  232.                 DoUpdate(window);
  233.  
  234.             activateEvt: 
  235.                 DoActivate(BAND(event.modifiers, activeFlag) <> 0, window);
  236.  
  237.         end;  { case }
  238.     end;  { DoWindowEvent }
  239.  
  240.     procedure ProcessEvent;
  241.         const
  242.             kHighLevelEvent = 23;        { copied from "EPPC.p" }
  243.         var
  244.             event: EventRecord;
  245.             gotEvent: Boolean;
  246.     begin
  247.  
  248.         gotEvent := WaitNextEvent(everyEvent, event, gSleepTime, gMouseRgn);
  249.  
  250. { give text services a chance to intercept this event }
  251.         if (gHasTextServices) then
  252.             if TSMEvent(event) then
  253.                 ;
  254.  
  255. { adjust cursor shape and set mouse region }
  256. { (we assume event.where is the current mouse position in global coordinates }
  257. { if event.what <= osEvt; high-level events store the event ID there) }
  258.  
  259.         if (event.what <= osEvt) then
  260.             AdjustCursor(event.where, gMouseRgn);
  261.  
  262. { dispatch on event.what }
  263.         case event.what of
  264.  
  265.             nullEvent: 
  266.                 DoNullEvent(event);
  267.  
  268.             mouseDown: 
  269.                 DoMouseDown(event);
  270.  
  271.             keyDown, autoKey: 
  272.                 DoKeyDown(event);
  273.  
  274.             updateEvt, activateEvt: 
  275.                 DoWindowEvent(event);
  276.  
  277.             diskEvt: 
  278.                 DoDiskEvent(event);
  279.  
  280.             osEvt: 
  281.                 DoOSEvent(event);
  282.  
  283.             kHighLevelEvent: 
  284.                 DoHighLevelEvent(event);
  285.  
  286.             otherwise
  287.                 ;                                            { ignore other events }
  288.         end;  { case }
  289.  
  290.         if (gotEvent) then
  291.             gSleepTime := 0;                        { force early idle after non-idle event }
  292.  
  293.     end;  { ProcessEvent }
  294.  
  295.     function GotRequiredParams ({const} var ae: AppleEvent): OSErr;
  296.         var
  297.             returnedType: DescType;
  298.             actualSize: Size;
  299.             err: OSErr;
  300.     begin
  301.         err := AEGetAttributePtr(ae, keyMissedKeywordAttr, typeWildCard, returnedType, nil, 0, actualSize);
  302.         if (err = errAEDescNotFound) then
  303.             GotRequiredParams := noErr
  304.         else if (err = noErr) then
  305.             GotRequiredParams := errAEParamMissed
  306.         else
  307.             GotRequiredParams := err;
  308.     end;  { GotRequiredParams }
  309.  
  310.     function HandleOpenDocument ({const} var ae, reply: AppleEvent;
  311.                                     refCon: LongInt): OSErr;
  312.         var
  313.             docList: AEDescList;
  314.             keyword: AEKeyword;
  315.             returnedType: DescType;
  316.             actualSize: Size;
  317.             numberOfDocuments, i: LongInt;
  318.             fileSpec: FSSpec;
  319.  
  320.         procedure CheckErr (err: OSErr);
  321.         begin
  322.             if (err <> noErr) then
  323.                 begin
  324.                     HandleOpenDocument := err;
  325.                     err := AEDisposeDesc(docList);
  326.                     Exit(HandleOpenDocument);
  327.                 end;
  328.         end;  { CheckErr }
  329.  
  330.     begin
  331.         HandleOpenDocument := noErr;
  332.  
  333. { extract direct parameter from the Apple Event }
  334.         CheckErr(AEGetParamDesc(ae, keyDirectObject, typeAEList, docList));
  335.  
  336. { perform the recommended check for additional required parameters }
  337.         CheckErr(GotRequiredParams(ae));
  338.  
  339. { count the items in the list of aliases }
  340.         CheckErr(AECountItems(docList, numberOfDocuments));
  341.  
  342.         for i := 1 to numberOfDocuments do
  343.             begin
  344.  
  345. { coerce the nth alias to a file system specification record }
  346.                 CheckErr(AEGetNthPtr(docList, i, typeFSS, keyword, returnedType, @fileSpec, SizeOf(fileSpec), actualSize));
  347.  
  348. { open the specified file }
  349.                 CheckErr(CreateWindow(@fileSpec));
  350.             end;  { for }
  351.  
  352. { dispose of the alias list }
  353.         CheckErr(AEDisposeDesc(docList));
  354.  
  355.     end;  { HandleOpenDocument }
  356.  
  357.     function HandleOpenApplication ({const} var ae, reply: AppleEvent;
  358.                                     refCon: LongInt): OSErr;
  359.         var
  360.             err: OSErr;
  361.     begin
  362.  
  363. { perform the recommended check for additional required parameters }
  364.         err := GotRequiredParams(ae);
  365.         if (err <> noErr) then
  366.             begin
  367.                 HandleOpenApplication := err;
  368.                 Exit(HandleOpenApplication);
  369.             end;
  370.  
  371. { create a new window from scratch }
  372.         HandleOpenApplication := CreateWindow(nil);
  373.  
  374.     end;  { HandleOpenApplication }
  375.  
  376.     function HandleQuitApplication ({const} var ae, reply: AppleEvent;
  377.                                     refCon: LongInt): OSErr;
  378.         var
  379.             optKey: AEKeyword;
  380.             actualType: DescType;
  381.             actualSize: Size;
  382.             saving: SavingOption;
  383.             err: OSErr;
  384.     begin
  385.  
  386. { default saving option is savingAsk }
  387.         saving := savingAsk;
  388.  
  389. { extract the optional save options }
  390.         err := AEGetParamPtr(ae, keyAESaveOptions, typeEnumerated, actualType, @optKey, SizeOf(optKey), actualSize);
  391.         if (err = noErr) then
  392.             begin
  393.                 if (optKey = kAEYes) then
  394.                     saving := savingYes
  395.                 else if (optKey = kAENo) then
  396.                     saving := savingNo
  397.                 else if (optKey <> kAEAsk) then
  398.                     begin
  399.                         HandleQuitApplication := paramErr;        { for want of a better code }
  400.                         Exit(HandleQuitApplication);
  401.                     end;
  402.             end;
  403.  
  404. { perform the recommended check for additional required parameters }
  405.         err := GotRequiredParams(ae);
  406.         if (err <> noErr) then
  407.             begin
  408.                 HandleQuitApplication := err;
  409.                 Exit(HandleQuitApplication);
  410.             end;
  411.  
  412.         HandleQuitApplication := DoQuit(saving);
  413.     end;  { HandleQuitApplication }
  414.  
  415. { THINK Pascal compiler directive: put the following code in the "Init" segment }
  416. {$S Init}
  417.  
  418.     function InitializeEvents: OSErr;
  419.  
  420.         procedure CheckErr (err: OSErr);
  421.         begin
  422.             if (err <> noErr) then
  423.                 begin
  424.                     InitializeEvents := err;
  425.                     Exit(InitializeEvents);
  426.                 end;
  427.         end;  { CheckErr }
  428.  
  429.     begin
  430.         InitializeEvents := noErr;
  431.  
  432. { allocate space for the mouse region }
  433.         gMouseRgn := NewRgn;
  434.  
  435. { install Apple event handlers for the Required Suite }
  436.         CheckErr(AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(@HandleOpenApplication), 0, false));
  437.         CheckErr(AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(@HandleOpenDocument), kDoOpen, false));
  438.         CheckErr(AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerProc(@HandleOpenDocument), kDoPrint, false));
  439.         CheckErr(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(@HandleQuitApplication), 0, false));
  440.  
  441. { install Apple event handlers for a subset of the Core Suite }
  442.         CheckErr(InstallCoreHandlers);
  443.  
  444. { install Apple event handlers for inline input }
  445.         CheckErr(WEInstallTSMHandlers);
  446.  
  447.     end;  { InitializeEvents }
  448.  
  449. end.